purpose of notebook
  1. summarize all insights and ideas from the other notebooks, as well as good exploratory plots
information
https://www.kaggle.com/sobhanmoosavi/us-weather-events https://smoosavi.org/datasets/lstw
Moosavi, Sobhan, Mohammad Hossein Samavatian, Arnab Nandi, Srinivasan Parthasarathy, and Rajiv Ramnath. “Short and Long-term Pattern Discovery Over Large-Scale Geo-Spatiotemporal Data.” In Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining, ACM, 2019.
Weather event is a spatiotemporal entity, where such an entity is associated with location and time. Following is the description of available weather event types:
Severe-Cold: The case of having extremely low temperature, with temperature below -23.7 degrees of Celsius. Fog: The case where there is low visibility condition as a result of fog or haze. Hail: The case of having solid precipitation including ice pellets and hail. Rain: The case of having rain, ranging from light to heavy. Snow: The case of having snow, ranging from light to heavy. Storm: The extremely windy condition, where the wind speed is at least 60 km/h. Other Precipitation: Any other type of precipitation which cannot be assigned to previously described event types.
The weather data is provided in terms of a CSV file with the following attributes: Attribute Description Nullable 1 EventId This is the identifier of a record No 2 Type The type of an event; examples are rain and snow. No 3 Severity The severity of an event, wherever applicable. Yes 4 StartTime (UTC) The start time of an event in UTC time zone. No 5 EndTime (UTC) The end time of an event in UTC time zone. No 6 TimeZone The US-based timezone based on the location of an event No (eastern, central, mountain, and pacific). 7 LocationLat The latitude in GPS coordinate. Yes 8 LocationLng The longitude in GPS coordinate. Yes 9 AirportCode The airport station that a weather event is reported from. Yes 10 City The city in address record. Yes 11 County The county in address record. Yes 12 State The state in address record. Yes 13 ZipCode The zipcode in address record. Yes

summary highlights

  1. there are questions about the acquisition of the data, since there seems to be a pattern to record at specific times (minutes)
  2. Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter
  3. there are starting times for Fog, mostly in the morning hours; Fog is also the longest events (on average)
  4. Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow
stories

(!) compare 4 big cities which are all close to the coast but vary in significantly in longitude and latitude (!) other possible subsets: variation across a state, type (one type distribution over country), severity (one type distribution over country), time range aggregation or reduction (i) spatial and time tracking of events, like rain clouds moving acorss the land

load packages
observations from clean nb
  1. columns: EventId chr, unique, not ordered, identifier in form of W- Type chr, categorical, not ordered, Severity chr, categorical, ordered, StartTime(UTC) S3: POSIXct, continuous, ordered, EndTime(UTC) S3: POSIXct, continuous, ordered, TimeZone chr, categorical, not ordered, LocationLat dbl, continuous, (not) ordered, Lng + Lat is same as AirportCode and ZipCode, thus may be viewed as categorical LocationLng dbl, continuous, (not) ordered, AirportCode chr, categorical, not ordered, (selection) can be dropped, same information as Lng + Lat City chr, categorical, not ordered, County chr, categorical, not ordered, (selection) can be dropped, same information as city State chr, categorical, not ordered, (selection) can be dropped, same information as city ZipCode dbl, categorical, not ordered, (selection) can be dropped, same information as Lng + Lat
  2. size of data set is 6274206 rows ! -> may be split up data set to process it or only work with aggregated data -> I decided to take only a small sub-population of the data set for this project = 4 big, popular cities along the coasts (reduced to 28094 rows) (other possible subsets: variation across a state, by type, severity, long/lat, time range)
  3. duplicated rows: (selection) no exact duplicates in rows
  4. missing values: (full data) only a few missing values in City and ZipCode, more in ZipCode (8) as in City (4), but when in ZipCode then also in City (as if it is a subset) but tricky to see since there are so much rows, might be single entries (-> may missing at random) or even all of them for this level imputation may be possible by hand or via cross check with other entries from the same location (only if missing at random) but for now no imputation or dropping needed (selection) no missing values
  5. it seems that airports close to each other report the same event, but may vary a little in StartTime and EndTime (selection only) City variable is the same information as ZipCode, County, State; also LocationLng&Lat are essentially location of reporting airport, thus redundant with AirportCode
  6. not much to clean, only converting chr which are categorical variables to fctr for more convenient use, and renaming to remove (UTC) to avoid confusion with the brackets, other wise Time and Gps variables have correct type (selection) dropping variables with redundant information after reducing the data set to four distinct sub-populations by City and reports from one of the present Airports (with most reporting)
insights from describe uni
  1. City: most observations/rows in New York, least are in Los Angeles with less than half; likely because the defined events occurred less often
  2. Type: mostly rain in Houston, New York and Seattle, only in Los Angeles is more fog than rain, overall is rain three times as much as fog on second place, (there is a lot of other precipitation only in New York, but for only from KJRB airport, which is now filtered out) snow mostly in New York and Seatlle, but cold in New York and Los Angeles, also overall not much, almost no storm and hail
  3. Severity: mostly are light, twice as much as as moderate, which seems also be twice as much as severe, as well as heavy which is again the half Los Angeles has more moderate, a lot more heavy in New York and Houston; Los Angeles has a lot severe compared to light -> because of missing rain? (unsure what UNK is, best guess is “unkonwn”, this is primarily in New York KJRB, which is now filtered out -> may be overlap with other precipitation from Type?)
  4. TimeZone: Los Angeles and Seattle both in Pacific, New York in Eastern, Houston in Central; Time zone information only relevant for knowing the day/night time since Time variables are in UTC for all observations
  5. Location Lng&Lat: same observation as for city, since we reduced to one airport per city (we can see the four cities across the us map, as well as that the reports are mostly from two airports, only in Houston from 4 airports, was before reduction to one airport each)
insights from describe uni time
  1. Seattle: events come in waves within the year (peak in Nov, low in Jul) but stable across years,
  2. Houston: events seem stable, spontaneous less in Jul and Nov,
  3. York: stable but jump to more in 2018, stable across week and year
  4. Los Angeles: kind of stable but spike around 2017 and increase 2019 and 2020, over week spikes on monday and thursday, little wave with peak in Jan and low an Jun, distribution over hours shows significant peak at 15:00
  5. all: distribution over month days always low at first and last two, distribution over minutes have (different, but all at end of hour) enormous peaks for each city
  6. since human judgment seems to be involved, the duration has peaks at the full hours, you even can see the dips in the poisson like distribution
  7. duration stats: Seattle median 60 min, q3 120 min; New York median 47 min q3 72 min; Los Angeles median 60 min q3 120 min, Houston median 60 min q3 98 min; Los Angeles and Seattle seem similar in distribution
insights from describe multi
  1. spearman correlation is rang based and needs at least ordinal scale, thus Type and City are out there is a small positive correlation between StartTime and Severity, since StartTime is mostly the increase in time over the years, thus Severity might gone up a little
  2. in Severity there are some gaps eg Rain and Snow have no Severe, where Fog has only Severe and Moderate, Cold and Storm come only in Severe, Hail only has Other these gaps make things hard to compare in Light Rain is most, but already in Moderate there is more Fog (because of Los Angeles)
  3. Fog seems to be longer than Rain, especially in Houston and Los Angeles; Los Angeles has no Snow but longer Cold periods (comparable to New York); Snow longest in New York and Seattle, but Seattle has less Cold, overall quite some severe fog overall
  4. Light and Moderate events are the most, there are less Severe events but there are also as long; Severe events in Houston and Seattle are quite long, Moderate is longer than usual in Los Angeles; may be most are Fog
type_severity_plot_point <- weather %>%
  ggplot(aes(x = fct_infreq(Type), y = fct_infreq(Severity), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    theme_minimal() +
    ggtitle("Severity over Type")
  
ggplotly(type_severity_plot_point)  
duration_type_plot_box <- weather %>%
  filter(as.numeric(Duration) < 600) %>%
  ggplot(aes(x = fct_infreq(Type), y = as.numeric(Duration), col = fct_infreq(City))) +
    geom_boxplot() +
    theme_minimal() +
    facet_grid(rows = vars(City)) +
    # coord_flip() +
    ggtitle("Duration over Type")

ggplotly(duration_type_plot_box)
insights from decribe multi time
  1. we can see the waves in the frequency of the events, but it seems that the duration is stable / constant, except for Los Angeles; may be the events are a little longer over the years on average
  2. Snow comes in seasons in New York and Seattle of course, but cold seem to increase in New York and Los Angeles since 2019 and not stick to winter season; Fog is mostly in Los Angeles and also increasing since 2019, Rain is present is all cities all the year, Seattle seems to have waves / seasons of Rain, and Los Angeles hast most year almost no Rain with spikes, funny is that in overall plot per city the snow seasons in New York did not really show, but in Seattle they really do, maybe since they sync with rain waves
  3. Severe events seem to increase since 2019, which might be Fog in Los Angeles
  4. can’t quite find the reason why there is so much reporting at specific fixed minutes, might be automated but trigger is unknown, but there is an interesting pattern here, might be because of recording method
  5. Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter
  6. Fog seems to have starting hours (and end): Houston 9 - 12 to 13 - 14, Los Angeles 14 - 16 to 15 - 19, New York 12 - 14 to 14 - 16, Seattle 13 - 16 to 15 - 18 all others are constant across hours of day
  7. Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow
month_type_plot_freq <- weather %>%
  mutate(month = month(StartTime, label = TRUE)) %>%
  ggplot(aes(x = month, y = fct_infreq(Type), col = fct_infreq(City))) +
    geom_jitter(alpha = 0.2, size = 0.5) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Month")

ggplotly(month_type_plot_freq)
year_type_plot_freq <- weather %>%
  mutate(year = year(StartTime)) %>%
  ggplot(aes(x = year, fill = fct_infreq(Type))) +
    geom_bar(position = position_dodge(preserve = "single")) +
    facet_grid(vars(City)) +
    theme_minimal() +
    ggtitle("Type over Year")

ggplotly(year_type_plot_freq)
position_dodge requires non-overlapping x intervals
LS0tDQp0aXRsZTogInN1bW1hcnkgZm9yIFVTIHdlYXRoZXIgZXZlbnQgZGF0YSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCi0tLQ0KcHVycG9zZSBvZiBub3RlYm9vaw0KLS0tDQoNCiAgKGkpIHN1bW1hcml6ZSBhbGwgaW5zaWdodHMgYW5kIGlkZWFzIGZyb20gdGhlIG90aGVyIG5vdGVib29rcywgYXMgd2VsbCBhcyBnb29kIGV4cGxvcmF0b3J5IHBsb3RzDQoNCi0tLQ0KaW5mb3JtYXRpb24NCi0tLQ0KaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9zb2JoYW5tb29zYXZpL3VzLXdlYXRoZXItZXZlbnRzDQpodHRwczovL3Ntb29zYXZpLm9yZy9kYXRhc2V0cy9sc3R3DQoNCk1vb3NhdmksIFNvYmhhbiwgTW9oYW1tYWQgSG9zc2VpbiBTYW1hdmF0aWFuLCBBcm5hYiBOYW5kaSwgU3Jpbml2YXNhbiBQYXJ0aGFzYXJhdGh5LCBhbmQgUmFqaXYgUmFtbmF0aC4g4oCcU2hvcnQgYW5kIExvbmctdGVybSBQYXR0ZXJuIERpc2NvdmVyeSBPdmVyIExhcmdlLVNjYWxlIEdlby1TcGF0aW90ZW1wb3JhbCBEYXRhLuKAnSBJbiBQcm9jZWVkaW5ncyBvZiB0aGUgMjV0aCBBQ00gU0lHS0REIEludGVybmF0aW9uYWwgQ29uZmVyZW5jZSBvbiBLbm93bGVkZ2UgRGlzY292ZXJ5ICYgRGF0YSBNaW5pbmcsIEFDTSwgMjAxOS4NCg0KV2VhdGhlciBldmVudCBpcyBhIHNwYXRpb3RlbXBvcmFsIGVudGl0eSwgd2hlcmUgc3VjaCBhbiBlbnRpdHkgaXMgYXNzb2NpYXRlZCB3aXRoIGxvY2F0aW9uIGFuZCB0aW1lLiBGb2xsb3dpbmcgaXMgdGhlIGRlc2NyaXB0aW9uIG9mIGF2YWlsYWJsZSB3ZWF0aGVyIGV2ZW50IHR5cGVzOg0KDQogICAgU2V2ZXJlLUNvbGQ6IFRoZSBjYXNlIG9mIGhhdmluZyBleHRyZW1lbHkgbG93IHRlbXBlcmF0dXJlLCB3aXRoIHRlbXBlcmF0dXJlIGJlbG93IC0yMy43IGRlZ3JlZXMgb2YgQ2Vsc2l1cy4NCiAgICBGb2c6IFRoZSBjYXNlIHdoZXJlIHRoZXJlIGlzIGxvdyB2aXNpYmlsaXR5IGNvbmRpdGlvbiBhcyBhIHJlc3VsdCBvZiBmb2cgb3IgaGF6ZS4NCiAgICBIYWlsOiBUaGUgY2FzZSBvZiBoYXZpbmcgc29saWQgcHJlY2lwaXRhdGlvbiBpbmNsdWRpbmcgaWNlIHBlbGxldHMgYW5kIGhhaWwuDQogICAgUmFpbjogVGhlIGNhc2Ugb2YgaGF2aW5nIHJhaW4sIHJhbmdpbmcgZnJvbSBsaWdodCB0byBoZWF2eS4NCiAgICBTbm93OiBUaGUgY2FzZSBvZiBoYXZpbmcgc25vdywgcmFuZ2luZyBmcm9tIGxpZ2h0IHRvIGhlYXZ5Lg0KICAgIFN0b3JtOiBUaGUgZXh0cmVtZWx5IHdpbmR5IGNvbmRpdGlvbiwgd2hlcmUgdGhlIHdpbmQgc3BlZWQgaXMgYXQgbGVhc3QgNjAga20vaC4NCiAgICBPdGhlciBQcmVjaXBpdGF0aW9uOiBBbnkgb3RoZXIgdHlwZSBvZiBwcmVjaXBpdGF0aW9uIHdoaWNoIGNhbm5vdCBiZSBhc3NpZ25lZCB0byBwcmV2aW91c2x5IGRlc2NyaWJlZCBldmVudCB0eXBlcy4NCg0KVGhlIHdlYXRoZXIgZGF0YSBpcyBwcm92aWRlZCBpbiB0ZXJtcyBvZiBhIENTViBmaWxlIHdpdGggdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOg0KICAgICAgQXR0cmlidXRlCSAgICAgICAgRGVzY3JpcHRpb24JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVsbGFibGUNCjEJICAgIEV2ZW50SWQJICAgICAgICAgIFRoaXMgaXMgdGhlIGlkZW50aWZpZXIgb2YgYSByZWNvcmQJICAgICAgICAgICAgICAgICAgICAgICAgTm8NCjIgICAJVHlwZQkgICAgICAgICAgICBUaGUgdHlwZSBvZiBhbiBldmVudDsgZXhhbXBsZXMgYXJlIHJhaW4gYW5kIHNub3cuCSAgICAgICAgICBObw0KMwkgICAgU2V2ZXJpdHkJICAgICAgICBUaGUgc2V2ZXJpdHkgb2YgYW4gZXZlbnQsIHdoZXJldmVyIGFwcGxpY2FibGUuICAgICAgICAJICAgIFllcw0KNAkgICAgU3RhcnRUaW1lIChVVEMpCSAgVGhlIHN0YXJ0IHRpbWUgb2YgYW4gZXZlbnQgaW4gVVRDIHRpbWUgem9uZS4gICAgICAgICAgCSAgICBObw0KNQkgICAgRW5kVGltZSAoVVRDKQkgICAgVGhlIGVuZCB0aW1lIG9mIGFuIGV2ZW50IGluIFVUQyB0aW1lIHpvbmUuCSAgICAgICAgICAgICAgICBObw0KNgkgICAgVGltZVpvbmUJICAgICAgICBUaGUgVVMtYmFzZWQgdGltZXpvbmUgYmFzZWQgb24gdGhlIGxvY2F0aW9uIG9mIGFuIGV2ZW50ICAgICBObw0KICAgICAgICAgICAgICAgICAgICAgICAgKGVhc3Rlcm4sIGNlbnRyYWwsIG1vdW50YWluLCBhbmQgcGFjaWZpYykuCQ0KNwkgICAgTG9jYXRpb25MYXQJICAgICAgVGhlIGxhdGl0dWRlIGluIEdQUyBjb29yZGluYXRlLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQo4ICAgCUxvY2F0aW9uTG5nCSAgICAgIFRoZSBsb25naXR1ZGUgaW4gR1BTIGNvb3JkaW5hdGUuCSAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQo5CSAgICBBaXJwb3J0Q29kZQkgICAgICBUaGUgYWlycG9ydCBzdGF0aW9uIHRoYXQgYSB3ZWF0aGVyIGV2ZW50IGlzIHJlcG9ydGVkIGZyb20uCVllcw0KMTAJICBDaXR5CSAgICAgICAgICAgIFRoZSBjaXR5IGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTEJICBDb3VudHkJICAgICAgICAgIFRoZSBjb3VudHkgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTIJICBTdGF0ZQkgICAgICAgICAgICBUaGUgc3RhdGUgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KMTMJICBaaXBDb2RlCSAgICAgICAgICBUaGUgemlwY29kZSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KDQotLS0NCnN1bW1hcnkgaGlnaGxpZ2h0cw0KLS0tDQoNCiAgKGkpIHRoZXJlIGFyZSBxdWVzdGlvbnMgYWJvdXQgdGhlIGFjcXVpc2l0aW9uIG9mIHRoZSBkYXRhLCBzaW5jZSB0aGVyZSBzZWVtcyB0byBiZSBhIHBhdHRlcm4gdG8gcmVjb3JkIGF0IHNwZWNpZmljIHRpbWVzIChtaW51dGVzKQ0KICAoaSkgSG91c3RvbiBoYXMgY29uc3RhbnQgUmFpbiBhbmQgbGVzcyBGb2cgaW4gU3VtbWVyOyBMb3MgQW5nZWxlcyBoYXMgbm8gUmFpbiBpbiBTdW1tZXIsIGJ1dCBjb25zdGFudCBGb2cgYW5kIGFsc28gQ29sZDsgTmV3IFlvcmsgaGFzIGNvbnN0YW50IFJhaW4gYW5kIEZvZywgU25vdyBpbiBXaW50ZXIsIENvbGQgICAgICAgICAgYWxzbyBhbGwgWWVhcjsgU2VhdHRsZSBoYXMgbGVzcyBSYWluIGluIFN1bW1lciwgRm9nIGFuZCBTbm93IGluIFdpbnRlcg0KICAoaSkgdGhlcmUgYXJlIHN0YXJ0aW5nIHRpbWVzIGZvciBGb2csIG1vc3RseSBpbiB0aGUgbW9ybmluZyBob3VyczsgRm9nIGlzIGFsc28gdGhlIGxvbmdlc3QgZXZlbnRzIChvbiBhdmVyYWdlKQ0KICAoaSkgSG91c3RvbiBzdGFibGUgb3ZlciB5ZWFycywgTG9zIEFuZ2VsZXMgaW5jcmVhc2VkIENvbGQgYW5kIEZvZywgTmV3IFlvcmsgbW9zdGx5IHN0YWJsZSwgYnV0IGp1bXAgMjAxOSBpbiBDb2xkLCBTZWF0dGxlIGxpdHRsZSBpbmNyZWFzZSBpbiBGb2cgYW5kIGRlY3JlYXNlIGluIFNub3cNCg0KLS0tDQpzdG9yaWVzDQotLS0NCg0KICAoISkgY29tcGFyZSA0IGJpZyBjaXRpZXMgd2hpY2ggYXJlIGFsbCBjbG9zZSB0byB0aGUgY29hc3QgYnV0IHZhcnkgaW4gc2lnbmlmaWNhbnRseSBpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlDQogICghKSBvdGhlciBwb3NzaWJsZSBzdWJzZXRzOiANCiAgICAgICAgICAgIHZhcmlhdGlvbiBhY3Jvc3MgYSBzdGF0ZSwgDQogICAgICAgICAgICB0eXBlIChvbmUgdHlwZSBkaXN0cmlidXRpb24gb3ZlciBjb3VudHJ5KSwgDQogICAgICAgICAgICBzZXZlcml0eSAob25lIHR5cGUgZGlzdHJpYnV0aW9uIG92ZXIgY291bnRyeSksIA0KICAgICAgICAgICAgdGltZSByYW5nZSBhZ2dyZWdhdGlvbiBvciByZWR1Y3Rpb24NCiAgKGkpIHNwYXRpYWwgYW5kIHRpbWUgdHJhY2tpbmcgb2YgZXZlbnRzLCBsaWtlIHJhaW4gY2xvdWRzIG1vdmluZyBhY29yc3MgdGhlIGxhbmQgDQoNCi0tLQ0KbG9hZCBwYWNrYWdlcw0KLS0tDQpgYGB7ciBsb2FkIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgdGlkeSBkYXRhIGZyYW1lDQpsaWJyYXJ5KHBsb3RseSkgIyBtYWtlIGdncGxvdHMgaW50ZXJhY3RpdmUNCmxpYnJhcnkobHVicmlkYXRlKSAjIGZ1bmN0aW9ucyB0byB3b3JrIHdpdGggZGF0ZS10aW1lcyBhbmQgdGltZS1zcGFucw0KYGBgDQoNCi0tLQ0Kb2JzZXJ2YXRpb25zIGZyb20gY2xlYW4gbmINCi0tLQ0KDQogIChpKSBjb2x1bW5zOiBFdmVudElkICAgICAgICAgIGNociwgdW5pcXVlLCBub3Qgb3JkZXJlZCwgaWRlbnRpZmllciBpbiBmb3JtIG9mIFctPG51bWJlcj4NCiAgICAgICAgICAgICAgIFR5cGUgICAgICAgICAgICAgY2hyLCBjYXRlZ29yaWNhbCwgbm90IG9yZGVyZWQsDQogICAgICAgICAgICAgICBTZXZlcml0eSAgICAgICAgIGNociwgY2F0ZWdvcmljYWwsIG9yZGVyZWQsDQogICAgICAgICAgICAgICBTdGFydFRpbWUoVVRDKSAgIFMzOiBQT1NJWGN0LCBjb250aW51b3VzLCBvcmRlcmVkLA0KICAgICAgICAgICAgICAgRW5kVGltZShVVEMpICAgICBTMzogUE9TSVhjdCwgY29udGludW91cywgb3JkZXJlZCwNCiAgICAgICAgICAgICAgIFRpbWVab25lICAgICAgICAgY2hyLCBjYXRlZ29yaWNhbCwgbm90IG9yZGVyZWQsDQogICAgICAgICAgICAgICBMb2NhdGlvbkxhdCAgICAgIGRibCwgY29udGludW91cywgKG5vdCkgb3JkZXJlZCwgTG5nICsgTGF0IGlzIHNhbWUgYXMgQWlycG9ydENvZGUgYW5kIFppcENvZGUsIHRodXMgbWF5IGJlIHZpZXdlZCBhcyBjYXRlZ29yaWNhbA0KICAgICAgICAgICAgICAgTG9jYXRpb25MbmcgICAgICBkYmwsIGNvbnRpbnVvdXMsIChub3QpIG9yZGVyZWQsDQogICAgICAgICAgICAgICBBaXJwb3J0Q29kZSAgICAgIGNociwgY2F0ZWdvcmljYWwsIG5vdCBvcmRlcmVkLCAoc2VsZWN0aW9uKSBjYW4gYmUgZHJvcHBlZCwgc2FtZSBpbmZvcm1hdGlvbiBhcyBMbmcgKyBMYXQNCiAgICAgICAgICAgICAgIENpdHkgICAgICAgICAgICAgY2hyLCBjYXRlZ29yaWNhbCwgbm90IG9yZGVyZWQsDQogICAgICAgICAgICAgICBDb3VudHkgICAgICAgICAgIGNociwgY2F0ZWdvcmljYWwsIG5vdCBvcmRlcmVkLCAoc2VsZWN0aW9uKSBjYW4gYmUgZHJvcHBlZCwgc2FtZSBpbmZvcm1hdGlvbiBhcyBjaXR5DQogICAgICAgICAgICAgICBTdGF0ZSAgICAgICAgICAgIGNociwgY2F0ZWdvcmljYWwsIG5vdCBvcmRlcmVkLCAoc2VsZWN0aW9uKSBjYW4gYmUgZHJvcHBlZCwgc2FtZSBpbmZvcm1hdGlvbiBhcyBjaXR5DQogICAgICAgICAgICAgICBaaXBDb2RlICAgICAgICAgIGRibCwgY2F0ZWdvcmljYWwsIG5vdCBvcmRlcmVkLCAoc2VsZWN0aW9uKSBjYW4gYmUgZHJvcHBlZCwgc2FtZSBpbmZvcm1hdGlvbiBhcyBMbmcgKyBMYXQNCiAgKGkpIHNpemUgb2YgZGF0YSBzZXQgaXMgNjI3NDIwNiByb3dzICEgIC0+IG1heSBiZSBzcGxpdCB1cCBkYXRhIHNldCB0byBwcm9jZXNzIGl0IG9yIG9ubHkgd29yayB3aXRoIGFnZ3JlZ2F0ZWQgZGF0YQ0KICAgIC0+IEkgZGVjaWRlZCB0byB0YWtlIG9ubHkgYSBzbWFsbCBzdWItcG9wdWxhdGlvbiBvZiB0aGUgZGF0YSBzZXQgZm9yIHRoaXMgcHJvamVjdCA9IDQgYmlnLCBwb3B1bGFyIGNpdGllcyBhbG9uZyB0aGUgY29hc3RzIChyZWR1Y2VkIHRvIDI4MDk0IHJvd3MpDQogICAgICAob3RoZXIgcG9zc2libGUgc3Vic2V0czogdmFyaWF0aW9uIGFjcm9zcyBhIHN0YXRlLCBieSB0eXBlLCBzZXZlcml0eSwgbG9uZy9sYXQsIHRpbWUgcmFuZ2UpDQogIChpKSBkdXBsaWNhdGVkIHJvd3M6IChzZWxlY3Rpb24pIG5vIGV4YWN0IGR1cGxpY2F0ZXMgaW4gcm93cw0KICAoaSkgbWlzc2luZyB2YWx1ZXM6IChmdWxsIGRhdGEpIG9ubHkgYSBmZXcgbWlzc2luZyB2YWx1ZXMgaW4gQ2l0eSBhbmQgWmlwQ29kZSwgbW9yZSBpbiBaaXBDb2RlICg4KSBhcyBpbiBDaXR5ICg0KSwgYnV0IHdoZW4gaW4gWmlwQ29kZSB0aGVuIGFsc28gaW4gQ2l0eSAoYXMgaWYgaXQgaXMgYSBzdWJzZXQpDQogICAgICAgICAgYnV0IHRyaWNreSB0byBzZWUgc2luY2UgdGhlcmUgYXJlIHNvIG11Y2ggcm93cywgbWlnaHQgYmUgc2luZ2xlIGVudHJpZXMgKC0+IG1heSBtaXNzaW5nIGF0IHJhbmRvbSkgb3IgZXZlbiBhbGwgb2YgdGhlbSBmb3IgdGhpcyBsZXZlbCANCiAgICAgICAgaW1wdXRhdGlvbiBtYXkgYmUgcG9zc2libGUgYnkgaGFuZCBvciB2aWEgY3Jvc3MgY2hlY2sgd2l0aCBvdGhlciBlbnRyaWVzIGZyb20gdGhlIHNhbWUgbG9jYXRpb24gKG9ubHkgaWYgbWlzc2luZyBhdCByYW5kb20pDQogICAgICAgICAgYnV0IGZvciBub3cgbm8gaW1wdXRhdGlvbiBvciBkcm9wcGluZyBuZWVkZWQNCiAgICAgICAgKHNlbGVjdGlvbikgbm8gbWlzc2luZyB2YWx1ZXMNCiAgKGkpIGl0IHNlZW1zIHRoYXQgYWlycG9ydHMgY2xvc2UgdG8gZWFjaCBvdGhlciByZXBvcnQgdGhlIHNhbWUgZXZlbnQsIGJ1dCBtYXkgdmFyeSBhIGxpdHRsZSBpbiBTdGFydFRpbWUgYW5kIEVuZFRpbWUgDQogICAgICAoc2VsZWN0aW9uIG9ubHkpIENpdHkgdmFyaWFibGUgaXMgdGhlIHNhbWUgaW5mb3JtYXRpb24gYXMgWmlwQ29kZSwgQ291bnR5LCBTdGF0ZTsgDQogICAgICAgIGFsc28gTG9jYXRpb25MbmcmTGF0IGFyZSBlc3NlbnRpYWxseSBsb2NhdGlvbiBvZiByZXBvcnRpbmcgYWlycG9ydCwgdGh1cyByZWR1bmRhbnQgd2l0aCBBaXJwb3J0Q29kZQ0KICAoaSkgbm90IG11Y2ggdG8gY2xlYW4sIG9ubHkgY29udmVydGluZyBjaHIgd2hpY2ggYXJlIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB0byBmY3RyIGZvciBtb3JlIGNvbnZlbmllbnQgdXNlLCANCiAgICAgIGFuZCByZW5hbWluZyB0byByZW1vdmUgKFVUQykgdG8gYXZvaWQgY29uZnVzaW9uIHdpdGggdGhlIGJyYWNrZXRzLCBvdGhlciB3aXNlIFRpbWUgYW5kIEdwcyB2YXJpYWJsZXMgaGF2ZSBjb3JyZWN0IHR5cGUNCiAgICAgIChzZWxlY3Rpb24pIGRyb3BwaW5nIHZhcmlhYmxlcyB3aXRoIHJlZHVuZGFudCBpbmZvcm1hdGlvbiBhZnRlciByZWR1Y2luZyB0aGUgZGF0YSBzZXQgdG8gZm91ciBkaXN0aW5jdCBzdWItcG9wdWxhdGlvbnMgDQogICAgICAgIGJ5IENpdHkgYW5kIHJlcG9ydHMgZnJvbSBvbmUgb2YgdGhlIHByZXNlbnQgQWlycG9ydHMgKHdpdGggbW9zdCByZXBvcnRpbmcpDQoNCi0tLQ0KaW5zaWdodHMgZnJvbSBkZXNjcmliZSB1bmkNCi0tLQ0KICANCiAgKGkpIENpdHk6IG1vc3Qgb2JzZXJ2YXRpb25zL3Jvd3MgaW4gTmV3IFlvcmssIGxlYXN0IGFyZSBpbiBMb3MgQW5nZWxlcyB3aXRoIGxlc3MgdGhhbiBoYWxmOyBsaWtlbHkgYmVjYXVzZSB0aGUgZGVmaW5lZCBldmVudHMgb2NjdXJyZWQgbGVzcyBvZnRlbiANCiAgKGkpIFR5cGU6DQogICAgICBtb3N0bHkgcmFpbiBpbiBIb3VzdG9uLCBOZXcgWW9yayBhbmQgU2VhdHRsZSwgb25seSBpbiBMb3MgQW5nZWxlcyBpcyBtb3JlIGZvZyB0aGFuIHJhaW4sIG92ZXJhbGwgaXMgcmFpbiB0aHJlZSB0aW1lcyBhcyBtdWNoIGFzIGZvZyBvbiBzZWNvbmQgcGxhY2UsIA0KICAgICAgKHRoZXJlIGlzIGEgbG90IG9mIG90aGVyIHByZWNpcGl0YXRpb24gb25seSBpbiBOZXcgWW9yaywgYnV0IGZvciBvbmx5IGZyb20gS0pSQiBhaXJwb3J0LCB3aGljaCBpcyBub3cgZmlsdGVyZWQgb3V0KQ0KICAgICAgc25vdyBtb3N0bHkgaW4gTmV3IFlvcmsgYW5kIFNlYXRsbGUsIGJ1dCBjb2xkIGluIE5ldyBZb3JrIGFuZCBMb3MgQW5nZWxlcywgYWxzbyBvdmVyYWxsIG5vdCBtdWNoLCANCiAgICAgIGFsbW9zdCBubyBzdG9ybSBhbmQgaGFpbA0KICAoaSkgU2V2ZXJpdHk6DQogICAgICBtb3N0bHkgYXJlIGxpZ2h0LCB0d2ljZSBhcyBtdWNoIGFzIGFzIG1vZGVyYXRlLCB3aGljaCBzZWVtcyBhbHNvIGJlIHR3aWNlIGFzIG11Y2ggYXMgc2V2ZXJlLCBhcyB3ZWxsIGFzIGhlYXZ5IHdoaWNoIGlzIGFnYWluIHRoZSBoYWxmDQogICAgICBMb3MgQW5nZWxlcyBoYXMgbW9yZSBtb2RlcmF0ZSwgYSBsb3QgbW9yZSBoZWF2eSBpbiBOZXcgWW9yayBhbmQgSG91c3RvbjsgTG9zIEFuZ2VsZXMgaGFzIGEgbG90IHNldmVyZSBjb21wYXJlZCB0byBsaWdodCAtPiBiZWNhdXNlIG9mIG1pc3NpbmcgcmFpbj8NCiAgICAgICh1bnN1cmUgd2hhdCBVTksgaXMsIGJlc3QgZ3Vlc3MgaXMgInVua29ud24iLCB0aGlzIGlzIHByaW1hcmlseSBpbiBOZXcgWW9yayBLSlJCLCB3aGljaCBpcyBub3cgZmlsdGVyZWQgb3V0IC0+IG1heSBiZSBvdmVybGFwIHdpdGggb3RoZXIgcHJlY2lwaXRhdGlvbiBmcm9tIFR5cGU/KQ0KICAoaSkgVGltZVpvbmU6IA0KICAgICAgTG9zIEFuZ2VsZXMgYW5kIFNlYXR0bGUgYm90aCBpbiBQYWNpZmljLCBOZXcgWW9yayBpbiBFYXN0ZXJuLCBIb3VzdG9uIGluIENlbnRyYWw7IA0KICAgICAgVGltZSB6b25lIGluZm9ybWF0aW9uIG9ubHkgcmVsZXZhbnQgZm9yIGtub3dpbmcgdGhlIGRheS9uaWdodCB0aW1lIHNpbmNlIFRpbWUgdmFyaWFibGVzIGFyZSBpbiBVVEMgZm9yIGFsbCBvYnNlcnZhdGlvbnMNCiAgKGkpIExvY2F0aW9uIExuZyZMYXQ6IHNhbWUgb2JzZXJ2YXRpb24gYXMgZm9yIGNpdHksIHNpbmNlIHdlIHJlZHVjZWQgdG8gb25lIGFpcnBvcnQgcGVyIGNpdHkNCiAgICAgICh3ZSBjYW4gc2VlIHRoZSBmb3VyIGNpdGllcyBhY3Jvc3MgdGhlIHVzIG1hcCwgYXMgd2VsbCBhcyB0aGF0IHRoZSByZXBvcnRzIGFyZSBtb3N0bHkgZnJvbSB0d28gYWlycG9ydHMsIG9ubHkgaW4gSG91c3RvbiBmcm9tIDQgYWlycG9ydHMsIA0KICAgICAgd2FzIGJlZm9yZSByZWR1Y3Rpb24gdG8gb25lIGFpcnBvcnQgZWFjaCkNCg0KLS0tDQppbnNpZ2h0cyBmcm9tIGRlc2NyaWJlIHVuaSB0aW1lDQotLS0NCiAgDQogIChpKSBTZWF0dGxlOiBldmVudHMgY29tZSBpbiB3YXZlcyB3aXRoaW4gdGhlIHllYXIgKHBlYWsgaW4gTm92LCBsb3cgaW4gSnVsKSBidXQgc3RhYmxlIGFjcm9zcyB5ZWFycywgDQogIChpKSBIb3VzdG9uOiBldmVudHMgc2VlbSBzdGFibGUsIHNwb250YW5lb3VzIGxlc3MgaW4gSnVsIGFuZCBOb3YsIA0KICAoaSkgWW9yazogc3RhYmxlIGJ1dCBqdW1wIHRvIG1vcmUgaW4gMjAxOCwgc3RhYmxlIGFjcm9zcyB3ZWVrIGFuZCB5ZWFyDQogIChpKSBMb3MgQW5nZWxlczoga2luZCBvZiBzdGFibGUgYnV0IHNwaWtlIGFyb3VuZCAyMDE3IGFuZCBpbmNyZWFzZSAyMDE5IGFuZCAyMDIwLCBvdmVyIHdlZWsgc3Bpa2VzIG9uIG1vbmRheSBhbmQgdGh1cnNkYXksIGxpdHRsZSB3YXZlIHdpdGggcGVhayBpbiBKYW4gYW5kIGxvdyBhbiBKdW4sIA0KICAgICAgZGlzdHJpYnV0aW9uIG92ZXIgaG91cnMgc2hvd3Mgc2lnbmlmaWNhbnQgcGVhayBhdCAxNTowMA0KICAoaSkgYWxsOiBkaXN0cmlidXRpb24gb3ZlciBtb250aCBkYXlzIGFsd2F5cyBsb3cgYXQgZmlyc3QgYW5kIGxhc3QgdHdvLCBkaXN0cmlidXRpb24gb3ZlciBtaW51dGVzIGhhdmUgKGRpZmZlcmVudCwgYnV0IGFsbCBhdCBlbmQgb2YgaG91cikgZW5vcm1vdXMgcGVha3MgZm9yIGVhY2ggY2l0eQ0KICAoaSkgc2luY2UgaHVtYW4ganVkZ21lbnQgc2VlbXMgdG8gYmUgaW52b2x2ZWQsIHRoZSBkdXJhdGlvbiBoYXMgcGVha3MgYXQgdGhlIGZ1bGwgaG91cnMsIHlvdSBldmVuIGNhbiBzZWUgdGhlIGRpcHMgaW4gdGhlIHBvaXNzb24gbGlrZSBkaXN0cmlidXRpb24NCiAgKGkpIGR1cmF0aW9uIHN0YXRzOiBTZWF0dGxlIG1lZGlhbiA2MCBtaW4sIHEzIDEyMCBtaW47IE5ldyBZb3JrIG1lZGlhbiA0NyBtaW4gcTMgNzIgbWluOyBMb3MgQW5nZWxlcyBtZWRpYW4gNjAgbWluIHEzIDEyMCBtaW4sIEhvdXN0b24gbWVkaWFuIDYwIG1pbiBxMyA5OCBtaW47IA0KICAgICAgTG9zIEFuZ2VsZXMgYW5kIFNlYXR0bGUgc2VlbSBzaW1pbGFyIGluIGRpc3RyaWJ1dGlvbg0KDQotLS0NCmluc2lnaHRzIGZyb20gZGVzY3JpYmUgbXVsdGkNCi0tLQ0KICANCiAgKGkpIHNwZWFybWFuIGNvcnJlbGF0aW9uIGlzIHJhbmcgYmFzZWQgYW5kIG5lZWRzIGF0IGxlYXN0IG9yZGluYWwgc2NhbGUsIHRodXMgVHlwZSBhbmQgQ2l0eSBhcmUgb3V0DQogICAgICB0aGVyZSBpcyBhIHNtYWxsIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gU3RhcnRUaW1lIGFuZCBTZXZlcml0eSwgc2luY2UgU3RhcnRUaW1lIGlzIG1vc3RseSB0aGUgaW5jcmVhc2UgaW4gdGltZSBvdmVyIHRoZSB5ZWFycywgdGh1cyBTZXZlcml0eSBtaWdodCBnb25lIHVwIGEgbGl0dGxlDQogIChpKSBpbiBTZXZlcml0eSB0aGVyZSBhcmUgc29tZSBnYXBzIGVnIFJhaW4gYW5kIFNub3cgaGF2ZSBubyBTZXZlcmUsIHdoZXJlIEZvZyBoYXMgb25seSBTZXZlcmUgYW5kIE1vZGVyYXRlLCBDb2xkIGFuZCBTdG9ybSBjb21lIG9ubHkgaW4gU2V2ZXJlLCBIYWlsIG9ubHkgaGFzIE90aGVyIA0KICAgICAgdGhlc2UgZ2FwcyBtYWtlIHRoaW5ncyBoYXJkIHRvIGNvbXBhcmUgDQogICAgICBpbiBMaWdodCBSYWluIGlzIG1vc3QsIGJ1dCBhbHJlYWR5IGluIE1vZGVyYXRlIHRoZXJlIGlzIG1vcmUgRm9nIChiZWNhdXNlIG9mIExvcyBBbmdlbGVzKQ0KICAoaSkgRm9nIHNlZW1zIHRvIGJlIGxvbmdlciB0aGFuIFJhaW4sIGVzcGVjaWFsbHkgaW4gSG91c3RvbiBhbmQgTG9zIEFuZ2VsZXM7IExvcyBBbmdlbGVzIGhhcyBubyBTbm93IGJ1dCBsb25nZXIgQ29sZCBwZXJpb2RzIChjb21wYXJhYmxlIHRvIE5ldyBZb3JrKTsgU25vdyBsb25nZXN0IGluIE5ldyBZb3JrIGFuZCAgICAgICAgU2VhdHRsZSwgYnV0IFNlYXR0bGUgaGFzIGxlc3MgQ29sZCwgb3ZlcmFsbCBxdWl0ZSBzb21lIHNldmVyZSBmb2cgb3ZlcmFsbCANCiAgKGkpIExpZ2h0IGFuZCBNb2RlcmF0ZSBldmVudHMgYXJlIHRoZSBtb3N0LCB0aGVyZSBhcmUgbGVzcyBTZXZlcmUgZXZlbnRzIGJ1dCB0aGVyZSBhcmUgYWxzbyBhcyBsb25nOw0KICAgICAgU2V2ZXJlIGV2ZW50cyBpbiBIb3VzdG9uIGFuZCBTZWF0dGxlIGFyZSBxdWl0ZSBsb25nLCBNb2RlcmF0ZSBpcyBsb25nZXIgdGhhbiB1c3VhbCBpbiBMb3MgQW5nZWxlczsgbWF5IGJlIG1vc3QgYXJlIEZvZw0KDQpgYGB7cn0NCnR5cGVfc2V2ZXJpdHlfcGxvdF9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfaW5mcmVxKFR5cGUpLCB5ID0gZmN0X2luZnJlcShTZXZlcml0eSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlNldmVyaXR5IG92ZXIgVHlwZSIpDQogIA0KZ2dwbG90bHkodHlwZV9zZXZlcml0eV9wbG90X3BvaW50KSAgDQpgYGANCmBgYHtyfQ0KZHVyYXRpb25fdHlwZV9wbG90X2JveCA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfaW5mcmVxKFR5cGUpLCB5ID0gYXMubnVtZXJpYyhEdXJhdGlvbiksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9ib3hwbG90KCkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgICMgY29vcmRfZmxpcCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFR5cGUiKQ0KDQpnZ3Bsb3RseShkdXJhdGlvbl90eXBlX3Bsb3RfYm94KQ0KYGBgDQoNCi0tLQ0KaW5zaWdodHMgZnJvbSBkZWNyaWJlIG11bHRpIHRpbWUNCi0tLQ0KICANCiAgKGkpIHdlIGNhbiBzZWUgdGhlIHdhdmVzIGluIHRoZSBmcmVxdWVuY3kgb2YgdGhlIGV2ZW50cywgYnV0IGl0IHNlZW1zIHRoYXQgdGhlIGR1cmF0aW9uIGlzIHN0YWJsZSAvIGNvbnN0YW50LCBleGNlcHQgZm9yIExvcyBBbmdlbGVzOw0KICAgICAgbWF5IGJlIHRoZSBldmVudHMgYXJlIGEgbGl0dGxlIGxvbmdlciBvdmVyIHRoZSB5ZWFycyBvbiBhdmVyYWdlDQogIChpKSBTbm93IGNvbWVzIGluIHNlYXNvbnMgaW4gTmV3IFlvcmsgYW5kIFNlYXR0bGUgb2YgY291cnNlLCBidXQgY29sZCBzZWVtIHRvIGluY3JlYXNlIGluIE5ldyBZb3JrIGFuZCBMb3MgQW5nZWxlcyBzaW5jZSAyMDE5IGFuZCBub3Qgc3RpY2sgdG8gd2ludGVyIHNlYXNvbjsNCiAgICAgIEZvZyBpcyBtb3N0bHkgaW4gTG9zIEFuZ2VsZXMgYW5kIGFsc28gaW5jcmVhc2luZyBzaW5jZSAyMDE5LCANCiAgICAgIFJhaW4gaXMgcHJlc2VudCBpcyBhbGwgY2l0aWVzIGFsbCB0aGUgeWVhciwgU2VhdHRsZSBzZWVtcyB0byBoYXZlIHdhdmVzIC8gc2Vhc29ucyBvZiBSYWluLCBhbmQgTG9zIEFuZ2VsZXMgaGFzdCBtb3N0IHllYXIgYWxtb3N0IG5vIFJhaW4gd2l0aCBzcGlrZXMsIA0KICAgICAgZnVubnkgaXMgdGhhdCBpbiBvdmVyYWxsIHBsb3QgcGVyIGNpdHkgdGhlIHNub3cgc2Vhc29ucyBpbiBOZXcgWW9yayBkaWQgbm90IHJlYWxseSBzaG93LCBidXQgaW4gU2VhdHRsZSB0aGV5IHJlYWxseSBkbywgbWF5YmUgc2luY2UgdGhleSBzeW5jIHdpdGggcmFpbiB3YXZlcw0KICAoaSkgU2V2ZXJlIGV2ZW50cyBzZWVtIHRvIGluY3JlYXNlIHNpbmNlIDIwMTksIHdoaWNoIG1pZ2h0IGJlIEZvZyBpbiBMb3MgQW5nZWxlcw0KICAoaSkgY2FuJ3QgcXVpdGUgZmluZCB0aGUgcmVhc29uIHdoeSB0aGVyZSBpcyBzbyBtdWNoIHJlcG9ydGluZyBhdCBzcGVjaWZpYyBmaXhlZCBtaW51dGVzLCBtaWdodCBiZSBhdXRvbWF0ZWQgYnV0IHRyaWdnZXIgaXMgdW5rbm93biwgDQogICAgICBidXQgdGhlcmUgaXMgYW4gaW50ZXJlc3RpbmcgcGF0dGVybiBoZXJlLCBtaWdodCBiZSBiZWNhdXNlIG9mIHJlY29yZGluZyBtZXRob2QNCiAgKGkpIEhvdXN0b24gaGFzIGNvbnN0YW50IFJhaW4gYW5kIGxlc3MgRm9nIGluIFN1bW1lcjsgTG9zIEFuZ2VsZXMgaGFzIG5vIFJhaW4gaW4gU3VtbWVyLCBidXQgY29uc3RhbnQgRm9nIGFuZCBhbHNvIENvbGQ7IE5ldyBZb3JrIGhhcyBjb25zdGFudCBSYWluIGFuZCBGb2csIFNub3cgaW4gV2ludGVyLCBDb2xkICAgICAgICAgIGFsc28gYWxsIFllYXI7IFNlYXR0bGUgaGFzIGxlc3MgUmFpbiBpbiBTdW1tZXIsIEZvZyBhbmQgU25vdyBpbiBXaW50ZXINCiAgKGkpIEZvZyBzZWVtcyB0byBoYXZlIHN0YXJ0aW5nIGhvdXJzIChhbmQgZW5kKTogSG91c3RvbiA5IC0gMTIgdG8gMTMgLSAxNCwgTG9zIEFuZ2VsZXMgMTQgLSAxNiB0byAxNSAtIDE5LCBOZXcgWW9yayAxMiAtIDE0IHRvIDE0IC0gMTYsIFNlYXR0bGUgMTMgLSAxNiB0byAxNSAtIDE4DQogICAgICBhbGwgb3RoZXJzIGFyZSBjb25zdGFudCBhY3Jvc3MgaG91cnMgb2YgZGF5DQogIChpKSBIb3VzdG9uIHN0YWJsZSBvdmVyIHllYXJzLCBMb3MgQW5nZWxlcyBpbmNyZWFzZWQgQ29sZCBhbmQgRm9nLCBOZXcgWW9yayBtb3N0bHkgc3RhYmxlLCBidXQganVtcCAyMDE5IGluIENvbGQsIFNlYXR0bGUgbGl0dGxlIGluY3JlYXNlIGluIEZvZyBhbmQgZGVjcmVhc2UgaW4gU25vdw0KDQpgYGB7cn0NCm1vbnRoX3R5cGVfcGxvdF9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUobW9udGggPSBtb250aChTdGFydFRpbWUsIGxhYmVsID0gVFJVRSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IGZjdF9pbmZyZXEoVHlwZSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBNb250aCIpDQoNCmdncGxvdGx5KG1vbnRoX3R5cGVfcGxvdF9wb2ludCkNCmBgYA0KYGBge3J9DQp5ZWFyX3R5cGVfcGxvdF9mcmVxIDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZSh5ZWFyID0geWVhcihTdGFydFRpbWUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgZmlsbCA9IGZjdF9pbmZyZXEoVHlwZSkpKSArDQogICAgZ2VvbV9iYXIocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZShwcmVzZXJ2ZSA9ICJzaW5nbGUiKSkgKw0KICAgIGZhY2V0X2dyaWQodmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiVHlwZSBvdmVyIFllYXIiKQ0KDQpnZ3Bsb3RseSh5ZWFyX3R5cGVfcGxvdF9mcmVxKQ0KYGBgDQoNCg0KDQoNCg0K